package UI

import (
	. "SGEngine"
	"github.com/gl"
)

const (
	TEXTURE_SLICE  = 0
	TEXTURE_SAMPLE = 1
)

type UITexture struct {
	*UINode

	TexType int

	arrayV         []float32
	W1, W2, H1, H2 float32

	BorderTop    float32
	BorderLeft   float32
	BorderRight  float32
	BorderBottom float32

	VBufferID   gl.Buffer
	TexBufferID gl.Buffer
	Tex         *ACTexture
	MProgram    *Program
	MColor      Color4

	TestI int
	SSS   int
}

func NewUITexture(imgpath string) *UITexture {
	return NewUITextureByType(imgpath, TEXTURE_SAMPLE)
}

func NewUITextureByType(imgpath string, _type int) *UITexture {
	RTexTure := new(UITexture)
	RTexTure.UINode = NewUINode()
	RTexTure.TexType = _type
	RTexTure.Tex = ACTextureMgr.LoadTexture(imgpath)
	RTexTure.NodeRender = RTexTure
	if _type == TEXTURE_SAMPLE {
		RTexTure.VBufferID = ACBufferMgr.GetVertexBuffer(BUFFER_Quad)
		RTexTure.TexBufferID = ACBufferMgr.GetTexBuffer(BUFFER_Quad)
		RTexTure.SetSize(float64(RTexTure.Tex.Img.Bounds().Dx()), float64(RTexTure.Tex.Img.Bounds().Dy()), 1)
	}

	RTexTure.MProgram = ACProgramMgr.GetProgram(PROGRAM_IMG)
	uniformTexture := RTexTure.MProgram.ProgramObject.GetUniformLocation("s_texture")
	RTexTure.MColor = NewColor4(1, 1, 1, 1)
	uniformTexture.Uniform1i(0)
	RTexTure.MProgram.ProgramObject.GetUniformLocation("inColor").Uniform4f(RTexTure.MColor.R, RTexTure.MColor.G, RTexTure.MColor.B, RTexTure.MColor.A)
	return RTexTure
}

func (u *UITexture) InitWithBorder(Top, Bottom, Left, Right float32) {
	u.BorderTop = Top
	u.BorderBottom = Bottom
	u.BorderLeft = Left
	u.BorderRight = Right
	ImgWidth, ImgHeight := float32(u.Tex.Img.Bounds().Dx()), float32(u.Tex.Img.Bounds().Dy())
	HalfWidth := ImgWidth * 0.5
	HalfHeight := ImgHeight * 0.5

	H1 := (ImgHeight - Top) - HalfHeight
	H2 := -float32(ImgHeight-Bottom) + HalfHeight
	W1 := -float32(ImgWidth-Left) + HalfWidth
	W2 := float32(ImgWidth-Right) - HalfWidth
	u.H1, u.H2, u.W1, u.W2 = H1, H2, W1, W2
	u.SetIsSizeScale(false)
	u.VBufferID = gl.GenBuffer()
	u.VBufferID.Bind(gl.ARRAY_BUFFER)
	u.arrayV = make([]float32, 162, 162)
	u.FillVertexBy4Point(W1, W2, H1, H2, HalfWidth, HalfHeight)
	gl.BufferData(gl.ARRAY_BUFFER, 9*6*3*4, u.arrayV, gl.DYNAMIC_DRAW)
	u.TexBufferID = gl.GenBuffer()
	u.TexBufferID.Bind(gl.ARRAY_BUFFER)
	TX1 := float32(Left) / float32(ImgWidth)
	TX2 := 1 - float32(Right)/float32(ImgWidth)
	TY1 := 1 - float32(Top)/float32(ImgHeight)
	TY2 := float32(Bottom) / float32(ImgHeight)
	arrayT := []float32{
		//LT
		0, TY1,
		TX1, TY1,
		TX1, 1,
		0, TY1,
		TX1, 1,
		0, 1,
		//T
		TX1, TY1,
		TX2, TY1,
		TX2, 1,
		TX1, TY1,
		TX2, 1,
		TX1, 1,
		//RT
		TX2, TY1,
		1, TY1,
		1, 1,
		TX2, TY1,
		1, 1,
		TX2, 1,
		//LB
		0, 0,
		TX1, 0,
		TX1, TY2,
		0, 0,
		TX1, TY2,
		0, TY2,
		//B
		TX1, 0,
		TX2, 0,
		TX2, TY2,
		TX1, 0,
		TX2, TY2,
		TX1, TY2,
		//RB
		TX2, 0,
		1, 0,
		1, TY2,
		TX2, 0,
		1, TY2,
		TX2, TY2,
		//L
		0, TY2,
		TX1, TY2,
		TX1, TY1,
		0, TY2,
		TX1, TY1,
		0, TY1,
		//R
		TX2, TY2,
		1, TY2,
		1, TY1,
		TX2, TY2,
		1, TY1,
		TX2, TY1,
		//C
		TX1, TY2,
		TX2, TY2,
		TX2, TY1,
		TX1, TY2,
		TX2, TY1,
		TX1, TY1,
	}
	gl.BufferData(gl.ARRAY_BUFFER, 9*6*2*4, arrayT, gl.STATIC_DRAW)
}
func (u *UITexture) SetSize(X, Y, Z float64) {
	if u.TexType == TEXTURE_SAMPLE {
		u.Node.SetSize(X, Y, Z)
		return
	}

	u.ReSize(X, Y, Z)
}

func (u *UITexture) FillVertexBy4Point(W1, W2, H1, H2, HalfWidth, HalfHeight float32) {
	//u.Node.SetSize(float64(HalfWidth)*2, float64(HalfHeight)*2, 1)
	//LT
	u.arrayV[0], u.arrayV[1], u.arrayV[2] = -HalfWidth, H1, 0
	u.arrayV[3], u.arrayV[4], u.arrayV[5] = W1, H1, 0
	u.arrayV[6], u.arrayV[7], u.arrayV[8] = W1, HalfHeight, 0
	u.arrayV[9], u.arrayV[10], u.arrayV[11] = -HalfWidth, H1, 0
	u.arrayV[12], u.arrayV[13], u.arrayV[14] = W1, HalfHeight, 0
	u.arrayV[15], u.arrayV[16], u.arrayV[17] = -HalfWidth, HalfHeight, 0
	//T
	u.arrayV[18], u.arrayV[19], u.arrayV[20] = W1, H1, 0
	u.arrayV[21], u.arrayV[22], u.arrayV[23] = W2, H1, 0
	u.arrayV[24], u.arrayV[25], u.arrayV[26] = W2, HalfHeight, 0
	u.arrayV[27], u.arrayV[28], u.arrayV[29] = W1, H1, 0
	u.arrayV[30], u.arrayV[31], u.arrayV[32] = W2, HalfHeight, 0
	u.arrayV[33], u.arrayV[34], u.arrayV[35] = W1, HalfHeight, 0
	//RT
	u.arrayV[36], u.arrayV[37], u.arrayV[38] = W2, H1, 0
	u.arrayV[39], u.arrayV[40], u.arrayV[41] = HalfWidth, H1, 0
	u.arrayV[42], u.arrayV[43], u.arrayV[44] = HalfWidth, HalfHeight, 0
	u.arrayV[45], u.arrayV[46], u.arrayV[47] = W2, H1, 0
	u.arrayV[48], u.arrayV[49], u.arrayV[50] = HalfWidth, HalfHeight, 0
	u.arrayV[51], u.arrayV[52], u.arrayV[53] = W2, HalfHeight, 0
	//LB
	u.arrayV[54], u.arrayV[55], u.arrayV[56] = -HalfWidth, -HalfHeight, 0
	u.arrayV[57], u.arrayV[58], u.arrayV[59] = W1, -HalfHeight, 0
	u.arrayV[60], u.arrayV[61], u.arrayV[62] = W1, H2, 0
	u.arrayV[63], u.arrayV[64], u.arrayV[65] = -HalfWidth, -HalfHeight, 0
	u.arrayV[66], u.arrayV[67], u.arrayV[68] = W1, H2, 0
	u.arrayV[69], u.arrayV[70], u.arrayV[71] = -HalfWidth, H2, 0
	//B
	u.arrayV[72], u.arrayV[73], u.arrayV[74] = W1, -HalfHeight, 0
	u.arrayV[75], u.arrayV[76], u.arrayV[77] = W2, -HalfHeight, 0
	u.arrayV[78], u.arrayV[79], u.arrayV[80] = W2, H2, 0
	u.arrayV[81], u.arrayV[82], u.arrayV[83] = W1, -HalfHeight, 0
	u.arrayV[84], u.arrayV[85], u.arrayV[86] = W2, H2, 0
	u.arrayV[87], u.arrayV[88], u.arrayV[89] = W1, H2, 0
	//RB
	u.arrayV[90], u.arrayV[91], u.arrayV[92] = W2, -HalfHeight, 0
	u.arrayV[93], u.arrayV[94], u.arrayV[95] = HalfWidth, -HalfHeight, 0
	u.arrayV[96], u.arrayV[97], u.arrayV[98] = HalfWidth, H2, 0
	u.arrayV[99], u.arrayV[100], u.arrayV[101] = W2, -HalfHeight, 0
	u.arrayV[102], u.arrayV[103], u.arrayV[104] = HalfWidth, H2, 0
	u.arrayV[105], u.arrayV[106], u.arrayV[107] = W2, H2, 0
	//L
	u.arrayV[108], u.arrayV[109], u.arrayV[110] = -HalfWidth, H2, 0
	u.arrayV[111], u.arrayV[112], u.arrayV[113] = W1, H2, 0
	u.arrayV[114], u.arrayV[115], u.arrayV[116] = W1, H1, 0
	u.arrayV[117], u.arrayV[118], u.arrayV[119] = -HalfWidth, H2, 0
	u.arrayV[120], u.arrayV[121], u.arrayV[122] = W1, H1, 0
	u.arrayV[123], u.arrayV[124], u.arrayV[125] = -HalfWidth, H1, 0
	//R
	u.arrayV[126], u.arrayV[127], u.arrayV[128] = W2, H2, 0
	u.arrayV[129], u.arrayV[130], u.arrayV[131] = HalfWidth, H2, 0
	u.arrayV[132], u.arrayV[133], u.arrayV[134] = HalfWidth, H1, 0
	u.arrayV[135], u.arrayV[136], u.arrayV[137] = W2, H2, 0
	u.arrayV[138], u.arrayV[139], u.arrayV[140] = HalfWidth, H1, 0
	u.arrayV[141], u.arrayV[142], u.arrayV[143] = W2, H1, 0
	//C
	u.arrayV[144], u.arrayV[145], u.arrayV[146] = W1, H2, 0
	u.arrayV[147], u.arrayV[148], u.arrayV[149] = W2, H2, 0
	u.arrayV[150], u.arrayV[151], u.arrayV[152] = W2, H1, 0
	u.arrayV[153], u.arrayV[154], u.arrayV[155] = W1, H2, 0
	u.arrayV[156], u.arrayV[157], u.arrayV[158] = W2, H1, 0
	u.arrayV[159], u.arrayV[160], u.arrayV[161] = W1, H1, 0

}

func (u *UITexture) ReSize(X, Y, Z float64) {
	if u.TexType == TEXTURE_SAMPLE {
		u.Node.SetSize(X, Y, Z)
		return
	}
	ImgWidth, ImgHeight := float32(X), float32(Y)
	HalfWidth := ImgWidth * 0.5
	HalfHeight := ImgHeight * 0.5
	H1 := (ImgHeight - u.BorderTop) - HalfHeight
	H2 := -float32(ImgHeight-u.BorderBottom) + HalfHeight
	W1 := -float32(ImgWidth-u.BorderLeft) + HalfWidth
	W2 := float32(ImgWidth-u.BorderRight) - HalfWidth
	u.FillVertexBy4Point(W1, W2, H1, H2, HalfWidth, HalfHeight)
	u.VBufferID.Bind(gl.ARRAY_BUFFER)
	//gl.BufferData(gl.ARRAY_BUFFER, 9*6*3*4, u.arrayV, gl.DYNAMIC_DRAW)
	gl.BufferSubData(gl.ARRAY_BUFFER, 0, 9*6*3*4, u.arrayV)
}

func (q *UITexture) Render() {
	//	gl.Enable(gl.ALPHA_TEST)
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	q.Tex.TexID.Bind(gl.TEXTURE_2D)
	q.MProgram.ProgramObject.Use()
	q.MProgram.ProgramObject.GetUniformLocation("inColor").Uniform4f(q.MColor.R, q.MColor.G, q.MColor.B, q.MColor.A)
	q.VBufferID.Bind(gl.ARRAY_BUFFER)
	q.MProgram.ProgramObject.GetAttribLocation("vPosition").AttribPointer(3, gl.FLOAT, false, 0, nil)
	q.MProgram.ProgramObject.GetAttribLocation("vPosition").EnableArray()
	q.TexBufferID.Bind(gl.ARRAY_BUFFER)
	q.MProgram.ProgramObject.GetAttribLocation("a_texCoord").AttribPointer(2, gl.FLOAT, false, 0, nil)
	q.MProgram.ProgramObject.GetAttribLocation("a_texCoord").EnableArray()
	if q.TexType == TEXTURE_SAMPLE {
		gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
	} else {
		gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
		gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
		gl.DrawArrays(gl.TRIANGLES, 0, 54)

	}
	q.VBufferID.Unbind(gl.ARRAY_BUFFER)
	q.TexBufferID.Unbind(gl.ARRAY_BUFFER)
	//gl.Disable(gl.ALPHA_TEST)
	gl.Disable(gl.BLEND)
	//q.Tex.TexID.Unbind(gl.TEXTURE_2D)
}
